import BubbleLayer from "../../Module/BubbleLayer";
import ModuleMgr from "../../Module/ModuleMgr";
import PlayerLayer from "../../Module/PlayerLayer";
import PropLayer from "../../Module/PropLayer";
import PorpLayer from "../../Module/PropLayer";
import TiledMapCtrl from "../../Module/TiledMapCtrl";
export default class MoveCtrl {

    private _playerLayer: PlayerLayer = null;
    //移动对象
    private _target: any = null;
    private _bubbleLayer: BubbleLayer = null;
    private _propLayer: PropLayer = null;
    constructor(target: any) {
        this._target = target;
        this._tiledMapCtrl = ModuleMgr.instance.getModule<TiledMapCtrl>("TiledMapCtrl");
        this._playerLayer = ModuleMgr.instance.getModule<PlayerLayer>("PlayerLayer");
        this._bubbleLayer = ModuleMgr.instance.getModule<BubbleLayer>("BubbleLayer");
        this._propLayer = ModuleMgr.instance.getModule<PropLayer>("PropLayer");
    }
    //移动的方向
    private _dir: cc.Vec2 = cc.v2(0, 0);
    get dir() {
        return this._dir;
    }
    set dir(dirIn: cc.Vec2) {
        this._dir = dirIn;
    }
    private _tiledMapCtrl: TiledMapCtrl = null;

    onUpdate(dt: number, ...rest: any[]) {
        //判断是否碰撞
        if (this.isColli()) {
            return;
        }
        this._target.node.x += this._target.speed * dt * this._dir.x;
        this._target.node.y += this._target.speed * dt * this._dir.y;
        //保存玩家的格子坐标
        this._target.playerTiledPos = this._tiledMapCtrl.getTiledPosByPoxiPos(this._target.node.position);
    }

    isColli() {
        let colliTile = this._tiledMapCtrl.getTiledPosByPoxiPos(this.getColliPos());
        //是否出界
        if (this._tiledMapCtrl.isOutOfMap(colliTile)) {
            return true;
        }
        //是否碰到障碍物
        let property = this._tiledMapCtrl.getPropertyByColliTiled(colliTile);
        if (!property) {
            //没有障碍物，可以获取到道具
            let propTs = this._propLayer.getPropByTiledPos(colliTile);
            if (propTs) {
                this._propLayer.removeProp(colliTile);
                this._propLayer.playEffect(propTs, this._target);
            }
            //没有属性判断是否有玩家，有玩家也不可以移动
            let player = this._playerLayer.getPlayerTsByTiledPos(colliTile);
            if (player) {
                //排除玩家自己
                if (this._target !== player) {
                    return true;
                }
            }
            //如果没有障碍物,但是有泡泡
            return this.colliBubble(this._target.playerTiledPos, colliTile);
        }
        if (property.colli) {
            if (property.push) {
                //箱子后面的坐标
                let colliNextTile = cc.v2(colliTile.x + this.dir.x, colliTile.y - this.dir.y);
                //箱子后面没有图块，
                //箱子出界也不能推动
                if (this._tiledMapCtrl.isOutOfMap(colliNextTile)) {
                    return true;
                }
                //箱子后面的格子坐标的属性
                let colliNextTileProperty = this._tiledMapCtrl.getPropertyByColliTiled(colliNextTile);
                //如果有属性，代表箱子后面有图块
                if (colliNextTileProperty) {
                    if (colliNextTileProperty.colli) {
                        return true;
                    }
                    this._pushBox(colliTile);
                    return false;
                }
                //如果后面是玩家，也不可以推
                if (this._playerLayer.getPlayerTsByTiledPos(colliNextTile)) {
                    return true;
                }
                //箱子后面有泡泡也不能推
                if (this._bubbleLayer.getBubbleByTiledPos(colliNextTile)) {
                    return true;
                }
                //箱子后面有道具，会将道具销毁
                let propTs = this._propLayer.getPropByTiledPos(colliNextTile);
                if (propTs) {
                    this._propLayer.removeProp(colliNextTile);
                }
                //传入的是碰撞点所在的格子坐标，也就是箱子所在的格子坐标
                this._pushBox(colliTile);
                return false;
            }

            return true;
        }
        if (property.visible) {
            //是草丛，可以碰撞，如果草丛中有泡泡，就不能碰撞
            return this.colliBubble(this._target.playerTiledPos, colliTile);
        }
        return false;
    }

    //判断碰撞泡泡的逻辑
    colliBubble(curPos: cc.Vec2, colliPos: cc.Vec2) {
        //如果玩家的位置和碰撞点的位置相同，玩家的位置和泡泡的位置相同，玩家可以移动
        if (curPos.equals(colliPos)) {
            return false;
        }
        //碰撞点的位置和泡泡的位置重合了，则不能移动
        let bubbleTs = this._bubbleLayer.getBubbleByTiledPos(colliPos);
        if (bubbleTs) {
            return true;
        }

    }
    //获取碰撞位置
    getColliPos() {
        let posX = this._dir.x * this._target.node.width / 2 + this._target.node.x;
        let posY = this._dir.y * this._target.node.height / 3 + this._target.node.y;
        return cc.v2(posX, posY);
    }

    private _pushBox(tiledPos: cc.Vec2) {
        //传入的参数：碰撞点所在的格子坐标，箱子移动的方向，箱子所在层
        //推动格子的下半部分
        let layerIndex = tiledPos.y + 1;
        this._tiledMapCtrl.moveBox(tiledPos, this._dir, layerIndex);
        //推动箱子的上半部分
        let upTilePos = cc.v2(tiledPos.x, tiledPos.y - 1);
        if (this._tiledMapCtrl.isOutOfMap(upTilePos)) {
            return;
        }
        this._tiledMapCtrl.moveBox(upTilePos, this._dir, layerIndex);
    }
}
